package www.sofn.com.order;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import www.sofn.com.accounts.AccountsService;
import www.sofn.com.accounts.domain.vo.WeChartMemberInfoVO;
import www.sofn.com.address.AddressService;
import www.sofn.com.address.domain.vo.AddressVO;
import www.sofn.com.exception.ValidateException;
import www.sofn.com.goods.GoodsDisplayService;
import www.sofn.com.goods.domain.vo.GoodsDisplayInfoVO;
import www.sofn.com.integral.IntegralService;
import www.sofn.com.member.MemberService;
import www.sofn.com.order.domain.dto.GoodsOrderDTO;
import www.sofn.com.order.domain.pojo.GoodsOrderPO;
import www.sofn.com.order.domain.query.OrderInfoQuery;
import www.sofn.com.order.domain.vo.CreateGoodsOrderVo;
import www.sofn.com.order.domain.vo.CreateShoppingCartGoodsOrderVo;
import www.sofn.com.order.domain.vo.OrderCountVO;
import www.sofn.com.order.domain.vo.OrderInfoVO;
import www.sofn.com.shopping.cart.ShoppingCartService;
import www.sofn.com.utils.GoodsUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GoodsOrderService {

    private final static ThreadLocal<GoodsOrderDTO> GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL=new ThreadLocal<>();

    @Resource
    private GoodsOrderMapper orderMapper;
    @Resource
    private GoodsDisplayService service;

    @Resource
    private AccountsService accountsService;
    @Resource
    private AddressService addressService;

    @Resource
    private MemberService memberService;

    @Resource
    private ShoppingCartService shoppingCartService;

    @Resource
    private IntegralService integralService;

    @Transactional
    public void createOrder(CreateGoodsOrderVo vo) {

        final GoodsDisplayInfoVO goodsVO = checkGoodsInfo(vo.getGoodsId());
        final Optional<GoodsDisplayInfoVO.AttrInfo> attrInfo = goodsVO.getGoodsAttr()
                .getAttrValue()
                .stream()
                .filter((v) -> StrUtil.equals(v.getId(), vo.getGoodsAttrId()))
                .findFirst();
        if (!attrInfo.isPresent()) throw new ValidateException("创建订单失败");
        //获取价格
        final BigDecimal memberPrice = attrInfo.get().getMemberPrice().setScale(2, RoundingMode.FLOOR);
        BigDecimal totalPrice = memberPrice.multiply(new BigDecimal(vo.getGoodsNum()));

        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        if (totalPrice.compareTo(personal.getIntegral()) == 1) {
            throw new ValidateException("当前会员积分不足");
        }

        GoodsOrderPO orderPO = new GoodsOrderPO();
        orderPO.setAddressInfo(
                checkAddressInfo(vo.getAddressId())
        );
        orderPO.setGoodsId(Long.valueOf(goodsVO.getId()))
                .setGoodsName(goodsVO.getGoodsName())
                .setCreateDate(LocalDateTime.now())
                .setGoodsNum(vo.getGoodsNum())
                .setGoodsTotalPrice(totalPrice)
                .setUnitPrice(attrInfo.get().getMemberPrice())
                .setMemberId(Long.valueOf(personal.getId()))
                .setGoodsAttrId(Long.valueOf(attrInfo.get().getId()))
                .setGoodsAttrName(attrInfo.get().getValue())
                .setDefaultGoodsImg(attrInfo.get().getImg());
        //获取默认图片
        if(StrUtil.isBlank(orderPO.getDefaultGoodsImg())){//如果属性中没用图片那默认轮播中的第一张图片
            orderPO.setDefaultGoodsImg(GoodsUtils.getGoodsDefaultImg(goodsVO.getGoodsCarousel()));
        }
        orderMapper.insert(orderPO);
        GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.set(new GoodsOrderDTO().setMemberId(personal.getId()).setTotalPrice(totalPrice).setIntegral(personal.getIntegral().setScale(2,RoundingMode.FLOOR)));
        deductionPoints();
        //  返还积分
        integralService.allocationIntegral(GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getTotalPrice(),GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getMemberId(),1);

        //移除线程变量
        removeGoodsOrderDTOThreadLocal();
    }

    //扣减积分
    private void deductionPoints(){
        //修改积分
        //todo 有线程安全问题 需要加锁
        BigDecimal residueIntegral=GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getIntegral().subtract(GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getTotalPrice()).setScale(2, RoundingMode.FLOOR);
        memberService.updateMemberIntegral(residueIntegral,GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getMemberId());
    }

    private GoodsDisplayInfoVO checkGoodsInfo(String goodsId){
        //获取商品信息
        final GoodsDisplayInfoVO goodsVO = service.getGoodsDisplayInfoById(goodsId);
        if (ObjectUtil.isNull(goodsVO)) throw new ValidateException("创建订单失败");
        return goodsVO;
    }


    private GoodsOrderPO.AddressInfo checkAddressInfo(String addressId) {
        //查询收货地址
        final AddressVO addressVO = addressService.getById(addressId);
        if (ObjectUtil.isNull(addressVO)) throw new ValidateException("收货地址无效！");
      return   new GoodsOrderPO.AddressInfo()
                .setAddress(addressVO.getProvinceName() + addressVO.getCityName() + addressVO.getCountyName() + addressVO.getStreetName())
                .setPhone(addressVO.getPhone()).setRecipient(addressVO.getRecipient());
    }


    private void removeGoodsOrderDTOThreadLocal(){
        GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.remove();
    }



    @Transactional
    public void createShoppingCartOrder(CreateShoppingCartGoodsOrderVo vo) {
        Set<String> shoppingCartId=new HashSet<>(); //购物车Id
        final GoodsOrderPO.AddressInfo addressInfo = checkAddressInfo(vo.getAddressId());//收货地址
        List<GoodsOrderPO> goodsOrderPOs=new ArrayList<>();
        Map<String,Integer> attrInfoMap=new HashMap<>();//key:属性id value 数量
        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.set(new GoodsOrderDTO().setMemberId(personal.getId()).setTotalPrice(BigDecimal.ZERO).setIntegral(personal.getIntegral().setScale(2,RoundingMode.FLOOR)));
        vo.getOrderInfos().forEach(v->{
            final GoodsDisplayInfoVO goodsVO = checkGoodsInfo(v.getGoodsId());
                String defaultGoodsImg=GoodsUtils.getGoodsDefaultImg(goodsVO.getGoodsCarousel());
            shoppingCartId.add(v.getShoppingCartId());
            v.getAttrInfos().stream().forEach(attrInfo->attrInfoMap.put(attrInfo.getId(),attrInfo.getNum()));
          //获取购买都商品sku
            final List<GoodsDisplayInfoVO.AttrInfo> attrInfoStream = goodsVO.getGoodsAttr().getAttrValue().stream().filter(attrInfo -> {
                return attrInfoMap.containsKey(attrInfo.getId());
            }).collect(Collectors.toList());
            BigDecimal totalPrice=BigDecimal.ZERO.setScale(2,RoundingMode.FLOOR);
            for (int i = 0; i < attrInfoStream.size(); i++) {
                //计算总价
                totalPrice= totalPrice.add( attrInfoStream.get(i).getMemberPrice().setScale(2,RoundingMode.FLOOR).multiply(new BigDecimal(attrInfoMap.get(attrInfoStream.get(i).getId()))));
                //生成订单数据
                GoodsOrderPO orderPO = new GoodsOrderPO();
                orderPO.setAddressInfo(
                        addressInfo
                );
                orderPO.setGoodsId(Long.valueOf(goodsVO.getId()))
                        .setGoodsName(goodsVO.getGoodsName())
                        .setCreateDate(LocalDateTime.now())
                        .setGoodsNum(attrInfoMap.get(attrInfoStream.get(i).getId()) )
                        .setGoodsTotalPrice(totalPrice)
                        .setUnitPrice(attrInfoStream.get(i).getMemberPrice())
                        .setMemberId(Long.valueOf(personal.getId()))
                        .setGoodsAttrId(Long.valueOf(attrInfoStream.get(i).getId()))
                        .setGoodsAttrName(attrInfoStream.get(i).getValue())
                        .setDefaultGoodsImg(StrUtil.isNotBlank(attrInfoStream.get(i).getImg())?attrInfoStream.get(i).getImg():defaultGoodsImg);
                //获取默认图片
                goodsOrderPOs.add(orderPO);
            }
            GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().setTotalPrice(totalPrice.add(GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getTotalPrice()));
        });
        //验证积分
        if (GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getTotalPrice().compareTo(personal.getIntegral()) == 1) {
            throw new ValidateException("当前会员积分不足");
        }
        goodsOrderPOs.forEach(orderitem->{//生成订单
            orderMapper.insert(orderitem);
        });
        //删除购物车
        shoppingCartService.delete(shoppingCartId);
        //扣减积分
        deductionPoints();
        //返还积分
        integralService.allocationIntegral(GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getTotalPrice(),GOODS_ORDER_DTO_THREAD_LOCALTHREAD_LOCAL.get().getMemberId(),1);
        //移除线程变量
        removeGoodsOrderDTOThreadLocal();
    }


    public List<OrderInfoVO> finalOrderInfo(OrderInfoQuery query) {
        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        return  orderMapper.finalOrderInfoByMemberId(personal.getId(), query);
    }

    public List<OrderCountVO> getOrderCount() {
        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        return orderMapper.getOrderCount(personal.getId());
    }
}
